package com.xust.oa.controller;

/**
 * @author zj
 * @time 2025/3/28 0:32
 */

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.annotation.Resource;

import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.seg.common.Term;
import com.xust.oa.domain.entity.KnowledgeBase;
import com.xust.oa.domain.entity.TermFreq;
import com.xust.oa.service.KnowledgeBaseService;
import com.xust.oa.service.TermFreqService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;


@RestController
@RequestMapping("deepSeek")
@Slf4j
public class AIController {
    //
    @Resource private KnowledgeBaseService knowledgeBaseService; // 本地知识库的录入

    @Value("${ai.config.deepseek.apiKey}")
    private String API_KEY;

    @Value("${ai.config.deepseek.baseUrl}")
    private String API_URL;

    @Autowired
    private TermFreqService termFreqService;

    // 用于保存每个用户的对话历史
    // https://api.deepseek.com/chat/completions 此接口为无状态接口,需要上下文连贯对话需要将历史聊天
    // 记录一并发送至接口中
    private final Map<String, List<Map<String, String>>> sessionHistory = new ConcurrentHashMap<>();
    private final ExecutorService executorService = Executors.newCachedThreadPool();
    private final ObjectMapper objectMapper = new ObjectMapper();

    @PostMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter chat(@RequestBody String questionStr) {



        // 用户标识
        String userId = "123"; // 或者从 token 中解析出用户 ID
        // Server send Events 服务器主动推送信息
        SseEmitter emitter = new SseEmitter(-1L);

        // 解析问题
        JSONObject json = JSON.parseObject(questionStr);
        String question = json.getString("question");

        if (question.length()>30)throw new RuntimeException("问题太长");
        List<Term> terms = HanLP.segment(question);
        for (Term term : terms) {
            String word = term.word;
            QueryWrapper<TermFreq> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("tag", word);
            if (termFreqService.getOne(queryWrapper) == null) {
                TermFreq termFreq = new TermFreq();
                termFreq.setTag(word);
                termFreq.setCount(1);
                termFreqService.save(termFreq);
            } else {
                TermFreq termFreq = termFreqService.getOne(queryWrapper);
                termFreq.setCount(termFreq.getCount() + 1);
                termFreqService.updateById(termFreq);
            }
        }
        executorService.execute(
                () -> {
                    try {
                        log.info("流式回答开始, 问题: {}", question);

                        // 1. 先查询本地知识库
                        KnowledgeBase similarKb = knowledgeBaseService.findMostSimilarQuestion(question);
                        if (similarKb != null && similarKb.getAnswer() != null) {
                            // 模拟流式返回本地答案
                            String answer = similarKb.getAnswer();
                            for (int i = 0; i < answer.length(); i += 3) {
                                int end = Math.min(i + 3, answer.length());
                                emitter.send(answer.substring(i, end));
                            }
                            emitter.complete();
                            return;
                        }

                        // 获取当前用户的对话历史
                        List<Map<String, String>> messages =
                                sessionHistory.getOrDefault(userId, new ArrayList<>());
                        // 添加用户的新问题到对话历史
                        Map<String, String> userMessage = new HashMap<>();
                        userMessage.put("role", "user");
                        userMessage.put("content", question);
                        Map<String, String> systemMessage = new HashMap<>();
                        systemMessage.put("role", "system");
                        systemMessage.put("content", "管理员");
                        messages.add(userMessage);
                        messages.add(systemMessage);
                        // 调用 Deepseek API
                        try (CloseableHttpClient client = HttpClients.createDefault()) {
                            HttpPost request = new HttpPost(API_URL);
                            request.setHeader("Content-Type", "application/json");
                            request.setHeader("Authorization", "Bearer " + API_KEY);
                            Map<String, Object> requestMap = new HashMap<>();
                            requestMap.put("model", "deepseek-chat");
                            requestMap.put("messages", messages); // 包含对话历史
                            requestMap.put("stream", true);
                            String requestBody = objectMapper.writeValueAsString(requestMap);
                            request.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
                            try (CloseableHttpResponse response = client.execute(request);
                                 BufferedReader reader =
                                         new BufferedReader(
                                                 new InputStreamReader(
                                                         response.getEntity().getContent(), StandardCharsets.UTF_8))) {
                                StringBuilder aiResponse = new StringBuilder();
                                String line;
                                while ((line = reader.readLine()) != null) {
                                    if (line.startsWith("data: ")) {
                                        System.err.println(line);
                                        String jsonData = line.substring(6);
                                        if ("[DONE]".equals(jsonData)) {
                                            break;
                                        }
                                        JsonNode node = objectMapper.readTree(jsonData);
                                        String content =
                                                node.path("choices").path(0).path("delta").path("content").asText("");
                                        if (!content.isEmpty()) {
                                            emitter.send(content);
                                            aiResponse.append(content); // 收集 AI 的回复
                                        }
                                    }
                                }
                                System.out.println("deepSeek的回答====>" + aiResponse.toString());
                                // 将 AI 的回复添加到对话历史
                                Map<String, String> aiMessage = new HashMap<>();
                                aiMessage.put("role", "assistant");
                                aiMessage.put("content", aiResponse.toString());
                                messages.add(aiMessage);
                                // 更新会话状态
                                sessionHistory.put(userId, messages);
                                log.info("流式回答结束, 问题: {}", question);
                                // 保存结果进入数据库
                                // KnowledgeBase knowledgeBase = new KnowledgeBase();
                                //
                                //
                                // knowledgeBase.setTitle(JSON.parseObject(question).getString("question"));
                                //                knowledgeBase.setContent(aiResponse.toString());
                                if (aiResponse.length() > 0) {
                                    KnowledgeBase newKb = new KnowledgeBase();
                                    newKb.setQuestion(question);
                                    newKb.setAnswer(aiResponse.toString());
                                    newKb.setCreatedAt(new Date(System.currentTimeMillis()));
                                    knowledgeBaseService.save(newKb);
                                }
                                // 表示已经推送玩所有的数据
                                emitter.complete();
                            }
                        }
                    } catch (Exception e) {
                        log.error("处理 Deepseek 请求时发生错误", e);
                        emitter.completeWithError(e);
                    }
                });
        return emitter;
    }
}
